package org.webby.security;

import org.webby.QueryStringUtil;

import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.HashMap;
import java.text.*;

/**
 * Contains a user ID, name, and optional expiry date. A null expiry date means the ticket never expires.
 */
public class AuthTicket {
  private static final DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.MEDIUM, Locale.US);

  private final String id;
  private final String name;
  private final Date expiry;

  public AuthTicket(String id, String name, Date expiry) {
    if (id == null) throw new IllegalArgumentException("id must be non-null");
    this.id = id;
    this.name = name;
    this.expiry = expiry;
  }

  public String getId() {
    return id;
  }

  public String getName() {
    return name;
  }

  public Date getExpiry() {
    return expiry;
  }

  public boolean isExpired() {
    return (expiry != null && expiry.before(new Date()));
  }

  public String toString() {
    Map map = new HashMap();
    map.put("id", id);
    if (name != null) map.put("name", name);
    if (expiry != null) map.put("expiry", dateFormat.format(expiry));
    return QueryStringUtil.createQueryString(map);
  }

  public static AuthTicket parse(String queryString) throws ParseException {
    Map<String, String> properties = QueryStringUtil.parse(queryString);

    String id = properties.get("id");
    if (id == null) {
      throw new IllegalArgumentException("missing id");
    }

    String name = properties.get("name");

    Date expiry = null;
    if (properties.get("expiry") != null) {
      try {
        expiry = dateFormat.parse(properties.get("expiry"));
      } catch (java.text.ParseException e) {
        throw new ParseException();
      }
    }

    return new AuthTicket(id, name, expiry);

  }

  public static void main(String[] args) throws ParseException {
    AuthTicket ticket1 = new AuthTicket("1", "john", new Date());
    System.out.println("ticket1: " + ticket1);
    String ticketStr = ticket1.toString();
    System.out.println("string form: " + ticketStr);
    AuthTicket ticket2 = AuthTicket.parse(ticketStr);
    System.out.println("ticket2: " + ticket2);
  }
}